home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c-part2 / 15777 < prev    next >
Encoding:
Internet Message Format  |  1996-08-05  |  6.1 KB

  1. Path: lrz-muenchen.de!news
  2. From: watzka@stat.uni-muenchen.de (Kurt Watzka)
  3. Newsgroups: comp.lang.c
  4. Subject: Re: (no subject)
  5. Date: 21 Apr 1996 20:20:17 GMT
  6. Organization: Leibniz-Rechenzentrum, Muenchen (Germany)
  7. Distribution: world
  8. Message-ID: <4le5a1$lg7@sparcserver.lrz-muenchen.de>
  9. References: <4le339$95a@ss.netgate.net>
  10. NNTP-Posting-Host: sun2.lrz-muenchen.de
  11.  
  12. Tamara Johnson <malihini@netgate.net> writes:
  13.  
  14. >/* Problem: Possible to pass a whole struct to 
  15. >            a function?
  16.  
  17. >            Requirement: create a function that will
  18. >            printf a union regardless of type (using a flag)
  19. >            using one struct containing the union and flag 
  20. >            (and etc.).
  21.  
  22. >  Don't need the solution, just need help passing the
  23. >  the struct and how to printf (point to?) individual 
  24. >  elements within. I *think* I can get the rest of it */
  25.  
  26. Have you actually tried to pass the struct to the function and
  27. access its members as you would access them anywhere else. If
  28. this does _not_ work, you are using an outdated version of a
  29. C compiler, because this method is "allowed" by a language 
  30. definition dating back to the late 80s.
  31.  
  32. >#include <stdlib.h>
  33. >#include <stdio.h>
  34. >#include <string.h>
  35.  
  36. >void Function1( void *P1, void *P2);
  37. >void Function2( void *P1);
  38.  
  39.  
  40. >   /* main ----------------------------- */
  41. >   void main()
  42.  
  43. I will not comment on this.
  44.  
  45. >   {
  46. >        union tag_1{
  47. >               float f;
  48. >               int i;
  49. >               char string[5];
  50. >               double d;
  51. >                    };
  52.  
  53. >        struct tag_2{
  54. >               union tag_1 Union; 
  55. >               int flag;
  56. >                   }Flag, *fP;
  57.  
  58. >       /* stuff to figure out if it's working to this point */
  59. >        Flag.flag=3;
  60. >        Flag.Union.f=5.3456;    
  61. >         /* conversion from 'const double '
  62. >            to 'float ', possible loss of data    
  63. >            NOTE: works ok                   */
  64. >        Flag.Union.d=78.9631;
  65.  
  66. You cannot do this with a union and expect the float field to 
  67. have a meaningful value after this assignment. Once you 
  68. assign a value to the double field, you _must_ consider all
  69. other fields to be undefined in standard C.
  70.  
  71. >        Flag.Union.i=31;
  72. >        strcpy(Flag.Union.string,"red");    
  73.  
  74. >        printf("main() Flag.Union.string: %s\n", 
  75. >                                           Flag.Union.string);
  76. >        printf("main() Flag.Union.i     : %i\n", Flag.Union.i);
  77. >        printf("main() Flag.Union.f     : %f\n", Flag.Union.f);
  78. >        printf("main() Flag.Union.d     : %f\n", Flag.Union.d);
  79.  
  80. >        printf("main() Flag.flag        : %i\n", Flag.flag);
  81.  
  82. >      /* end of stuff - is working when Function2 is deleted.
  83. >         Of course, whatever union member is initialized last
  84. >         is the one that follows thru, others will be
  85. >         essentially garbage */
  86.  
  87. >        Function1(Flag.Union.string, Flag.flag); /* Function1' 
  88. >                :pointer mismatch for actual parameter 2 
  89. >                NOTE: but appears to be functioning ok  
  90. >                      when Function2 deleted.
  91. >                      except passing individual elements, 
  92. >                      need to pass the whole struct */
  93.  
  94. Note that "Flag.flag" is an int, according to your definitions.
  95.  
  96. >     /*
  97. >        Function2(fP);
  98.  
  99. "fp" is an uninitialized pointer, at least I failed to see an
  100. assignment to that pointer. Using it may lead to interesting
  101. results.
  102.  
  103. Try inserting 
  104.  
  105.    fp = &Flag;
  106.  
  107. before you call Function2.
  108.  
  109. >     */
  110. >    }
  111. >   /* Function1 ------------------------------ */
  112. >   
  113. >   void Function1( void *P1, void *P2)
  114. >   {
  115.  
  116. >        printf("Function1 P1: %s\n", ( (char *)P1));
  117. >        printf("Function1 P2: %i\n", ( (int *)P2));
  118. >           
  119. >   }
  120.  
  121. This function is called with a pointer to the string literal "red"
  122. for "P1" and the integer 3 for "P2". You could successfully print
  123. p1 with
  124.  
  125.    printf("Function1 P1: %s\n", P1);
  126.  
  127. but I hope that telling you the whole treatment of the second formal
  128. parameter works by mere chance does not turn it into a bug of the
  129. "Schroedinger" class. The function expects a void *, but you pass it
  130. the value 3. This is an undefined conversion. To printf(), you promise
  131. that you will pass an int, but in fact you pass a pointer to int.
  132.  
  133. >   /* Function2 
  134. >   
  135. >   void Function2( void *P1)  /*NOTE: not working
  136.  
  137. You know more about this function that you are willing to tell your
  138. compiler about it. The argument is a "struct tag_2 *", and if you
  139. want to treat is as a such, either define Function2() as
  140.  
  141.     void Function2(struct tag_2 *P1)
  142.  
  143. or cast the void pointer passed to Function2() to a "struct tag_2 *".
  144.  
  145. To do this successfully, both the caller and the callee will have to
  146. have access to the definition of a "struct tag_2".
  147.  
  148. >   {
  149. >    /*
  150. >      printf("Function2 output:\n %s\n", 
  151. >                            ( (char *)P1->tag_1));
  152.  
  153. It is hard to figure what you want to do with that statement. The
  154. only time _I_ saw "tag_1" was during the definition of an enumerated
  155. type, so it is probably not the same "tag_1" that you use  in this
  156. statement.
  157.  
  158. >       
  159. >      printf("Function2\n");
  160. >      if(( (char *)P1).flag==3)    /* left of '.f' must have 
  161. >                                 struct/union type
  162. >                                 NOTE: not working         
  163.  
  164. A "char *" usually does not have a "flag" element. If you insist on
  165. passing "void *", and nothing but "void *" as function arguments,
  166. and if you pass a vaild pointer to a "struct tag2" to this function,
  167. what you want seems to be
  168.  
  169.    if (((struct tag2 *)P1)->flag == 3)
  170.  
  171. >      printf("Function2 output:\n %s\n", 
  172. >        ( (char *)P1->Union.string));
  173. >                /* left of '->Union' must point to 
  174. >                    struct/union
  175. >                   NOTE: not working                
  176. >   }                        
  177.  
  178.  
  179. >   /* ------------------ OUTPUT ---------------------------
  180. >     main() Flag.Union.string: red
  181. >     main() Flag.Union.i     : 6579570
  182. >     main() Flag.Union.f     : 0.000000
  183. >     main() Flag.Union.d     : 78.963074
  184. >     main() Flag.flag        : 3
  185. >     Function1 P1: red
  186. >     Function1 P2: 3
  187. >                    
  188.  
  189. Since the code you posted does not even compile, I wonder how you
  190. got that "OUTPUT".
  191.  
  192. Kurt
  193. --
  194. | Kurt Watzka                             Phone : +49-89-2180-6254
  195. | watzka@stat.uni-muenchen.de
  196.